﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System.Security;

namespace TotalApplication.Core
{
    public partial class PasswordEntryViewModel : BaseViewModel
    {
        #region Public Properties

        /// <summary>
        /// The label to identify what this value is for
        /// </summary>
        [ObservableProperty]
        private string? _label;

        /// <summary>
        /// The fake password to display a string
        /// </summary>
        [ObservableProperty]
        private string? _fakePassword;

        /// <summary>
        /// The current password's hint text to display when no password is set
        /// </summary>
        [ObservableProperty]
        private string? _currentPasswordHintText;

        /// <summary>
        /// The new password's hint text to display when no password is set
        /// </summary>
        [ObservableProperty]
        private string? _newPasswordHintText;

        /// <summary>
        /// The confirm password's hint text to display when no password is set
        /// </summary>
        [ObservableProperty]
        private string? _confirmPasswordHintText;

        /// <summary>
        /// The current saved value
        /// </summary>
        [ObservableProperty]
        private SecureString? _currentPassword;

        /// <summary>
        /// The current non-committed value
        /// </summary>
        [ObservableProperty]
        private SecureString? _newPassword;

        /// <summary>
        /// The current non-committed confirmed value
        /// </summary>
        [ObservableProperty]
        private SecureString? _confirmPassword;

        /// <summary>
        /// Indicates if the current text is in editing mode
        /// </summary>
        [ObservableProperty]
        private bool _editing;

        #endregion

        #region Commands

        /// <summary>
        /// Puts the control into editing mode
        /// </summary>
        [RelayCommand]
        private void Edit()
        {
            // Clear all password
            CurrentPassword = new SecureString();
            ConfirmPassword = new SecureString();

            Editing = true;
        }

        /// <summary>
        /// Cancels out of edit mode
        /// </summary>
        [RelayCommand]
        private void Cancel()
        {
            Editing = false;
        }

        /// <summary>
        /// Commits the edits and saves the value
        /// as well as goes back to non-editing mode
        /// </summary>
        [RelayCommand]
        private void Save()
        {
            // Make sure current password is correct
            // TODO: This will come from the real back-end store of this users password
            //       or via asking the web server to confirm the password
            var storedPassword = "Test1234";

            // Confirm current password is a match
            // TODO: Typically this isn't done here, but rather on the server
            if (storedPassword != CurrentPassword.Unsecure())
            {
                // Let user know the password is incorrect
                IoC.UI.ShowMessageBoxAsync(new MessageBoxDialogViewModel
                {
                    Title = "Incorrect Password",
                    Message = "The current password you entered is incorrect, please try again.",
                    OkText = "OK",
                });

                return;
            }

            // Now we check that the new password and confirm password match
            if (NewPassword.Unsecure() != ConfirmPassword.Unsecure())
            {
                // Let user know the password is incorrect
                IoC.UI.ShowMessageBoxAsync(new MessageBoxDialogViewModel
                {
                    Title = "Mismatched Password",
                    Message = "The new and confirm password do not match, please try again.",
                    OkText = "OK",
                });

                return;
            }

            // Check we actually have a new password
            if (NewPassword.Unsecure().Length == 0)
            {
                // Let user know the password is incorrect
                IoC.UI.ShowMessageBoxAsync(new MessageBoxDialogViewModel
                {
                    Title = "Password too short",
                    Message = "You must enter a password",
                    OkText = "OK",
                });

                return;
            }

            // Set the edited text to the original text
            CurrentPassword = new SecureString();
            foreach (var c in NewPassword.Unsecure().ToCharArray())
                CurrentPassword.AppendChar(c);

            Editing = false;
        }

        #endregion

        #region Constructor

        public PasswordEntryViewModel()
        {
            //Label = "Name";
            //OriginalText = "Tian zj is best";
            //EditedText = "Editing :)";
            //Editing = false;

            FakePassword = "********";
            NewPasswordHintText = "Enter new password";
            ConfirmPasswordHintText = "Enter confirm password";
            CurrentPasswordHintText = "Enter current password";
        }

        #endregion
    }
}
